package com.example.taskscheduling.service;

import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Random;
import java.util.concurrent.Future;

/**
 * 异步任务服务类
 * 用于定义需要异步执行的任务，避免耗时操作阻塞主线程
 * 配合@Async注解实现方法的异步调用
 */
@Service // 标识为Spring服务层组件，由Spring容器管理
public class AsyncTaskService {

    /**
     * 发送短信验证码的异步方法
     * 使用@Async注解标记，表明该方法会在独立的线程中执行，不阻塞调用者
     * 适用于处理耗时操作（如调用第三方短信接口、文件处理等）
     *
     * @throws InterruptedException 线程休眠可能抛出的中断异常
     */
    @Async // 声明方法为异步执行，需要在启动类添加@EnableAsync注解开启异步支持
    public void sendSMS() throws InterruptedException {
        // 打印方法开始执行的时间（去除纳秒，便于阅读）
        System.out.println(LocalDateTime.now().withNano(0) + "开始调用短信验证码业务方法");

        // 记录方法开始执行的时间戳，用于计算总耗时
        long startTime = System.currentTimeMillis();

        // 模拟耗时操作（如调用第三方短信API的网络延迟）
        // 线程休眠5000毫秒（5秒）
        Thread.sleep(5000);

        // 记录方法执行结束的时间戳
        long endTime = System.currentTimeMillis();

        // 打印方法执行完毕的时间
        System.out.println(LocalDateTime.now().withNano(0) + "短信验证码业务方法执行完毕");

        // 计算并打印方法总耗时（毫秒）
        System.out.println("执行短信业务方法总耗时：" + (endTime - startTime) + "ms");
    }

    /**
     * 异步统计指定地区销售额的方法
     * 使用@Async注解标记为异步方法，会在独立线程中执行
     * 返回Future类型结果，支持获取异步执行结果和判断任务是否完成
     *
     * @param area 要统计销售额的地区（如"华东区"、"华北区"）
     * @return Future<Integer> 异步任务的结果封装，包含统计得到的销售额
     * @throws InterruptedException 线程休眠可能抛出的中断异常
     */
    @Async // 声明为异步方法，需配合@EnableAsync使用以开启异步支持
    public Future<Integer> salesStatistics(String area) throws InterruptedException {
        // 打印开始统计的时间和地区信息（去除纳秒，便于阅读）
        System.out.println(LocalDateTime.now().withNano(0) + "开始统计【" + area + "】的销售额");

        // 记录方法开始执行的时间戳，用于计算总耗时
        long startTime = System.currentTimeMillis();

        // 生成1-5之间的随机整数，模拟不同地区统计所需的耗时差异
        int time = new Random().nextInt(5) + 1;

        // 模拟统计过程的耗时操作（线程休眠time秒）
        Thread.sleep(time * 1000);

        // 记录统计结束的时间戳
        long endTime = System.currentTimeMillis();

        // 打印统计完成的时间和地区信息
        System.out.println(LocalDateTime.now().withNano(0) + area + "地区销售额统计完毕");

        // 生成模拟的销售额数据（随机耗时+1000作为销售额）
        int m = time + 1000;

        // 打印该地区的销售额和统计总耗时
        System.out.println(area + "销售" + m + "元，统计总耗时：" + (endTime - startTime) + "ms");

        // 返回异步结果，使用AsyncResult封装销售额数据
        // 调用者可通过Future的get()方法获取结果（会阻塞直到结果返回）
        return new AsyncResult<Integer>(m);
    }
}